package com.ants.modules.ArticleView.controller;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.date.BetweenFormatter;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch.core.GetResponse;
import co.elastic.clients.elasticsearch.core.SearchRequest;
import co.elastic.clients.elasticsearch.core.SearchResponse;
import co.elastic.clients.elasticsearch.core.search.Hit;
import com.ants.common.annotation.AutoLog;
import com.ants.common.annotation.RateLimiter;
import com.ants.common.constant.CacheConstant;
import com.ants.common.system.api.ISysBaseAPI;
import com.ants.common.system.result.Result;
import com.ants.common.system.vo.LoginUser;
import com.ants.common.utils.MinioUtil;
import com.ants.common.utils.RestUtil;
import com.ants.modules.ArticleManage.dto.ArticleManageDto;
import com.ants.modules.ArticleManage.dto.SysUserVo;
import com.ants.modules.ArticleManage.entity.ArticleLikeCollection;
import com.ants.modules.ArticleManage.entity.ArticleManage;
import com.ants.modules.ArticleManage.service.ArticleLikeCollectionService;
import com.ants.modules.ArticleManage.service.ArticleManageService;
import com.ants.modules.ArticleManage.vo.ArticleManageVo;
import com.ants.modules.articleFavorites.entity.ArticleFavoritesSub;
import com.ants.modules.articleFavorites.service.ArticleFavoritesSubService;
import com.ants.modules.articleFollow.entity.ArticleFollow;
import com.ants.modules.articleFollow.service.ArticleFollowService;
import com.ants.modules.articleLable.entity.ArticleLable;
import com.ants.modules.articleLable.service.ArticleLableService;
import com.ants.modules.articleSort.entity.ArticleSort;
import com.ants.modules.articleSort.service.ArticleSortService;
import com.ants.modules.wxManage.service.AntsWxSwiperService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.stream.Collectors;

/**
 * TODO
 * Author Chen
 * Date   2022/12/12 17:51
 */
@Slf4j
@Api(tags = "微信小程序接口")
@RestController
@RequestMapping("/wxAppletView")
public class WxAppletController {

    @Autowired
    ISysBaseAPI sysBaseAPI;
    @Autowired
    AntsWxSwiperService wxSwiperService;
    @Autowired
    ArticleManageService articleManageService;
    @Autowired
    ArticleLikeCollectionService articleLikeCollectionService;
    @Autowired
    ArticleFavoritesSubService articleFavoritesSubService;
    @Autowired
    ArticleFollowService articleFollowService;

    @Autowired
    ArticleSortService articleSortService;
    @Autowired
    ArticleLableService articleLableService;

    @Value("${ants.path.upload}")
    private String upLoadPath;
    @Value(value = "${ants.minio.bucketName}")
    private String bucketName;
    @Autowired
    ElasticsearchClient restHighLevelClient;

    /**
     * @return
     * @功能：获取通用公共配置
     */
    @GetMapping("/queryWxConfig")
    @RateLimiter
    public Result<?> queryWxConfig() {
        Map<String, Object> map = new HashMap<>();
        // 获取小程序配置
        Map<String, Object> wxConfigMap = sysBaseAPI.getWxConfig();
        map.put("config", wxConfigMap);
        return Result.ok(map);
    }

    /**
     * 获取轮播图
     */
    @GetMapping("/querySwiper")
    @RateLimiter
    public Result<?> querySwiper() {
        List<Map<String, String>> list = wxSwiperService.getHomeSwiper();
        return Result.ok(list);
    }

    /**
     * 获取热门标签，文章量最多的前10个
     */
    @GetMapping("/queryHotLableBySize")
    @RateLimiter
    public Result<?> queryHotLableBySize(@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) {
        List<Map<String, String>> list = wxSwiperService.queryHotLableBySize(pageSize);
        return Result.ok(list);
    }

    /**
     * 获取热门标签，文章量最多的前10个
     */
    @GetMapping("/queryHotSortBySize")
    @RateLimiter
    public Result<?> queryHotSortBySize(@RequestParam(name = "pageSize", defaultValue = "5") Integer pageSize) {
        List<Map<String, Object>> list = articleManageService.queryHotSortBySize(pageSize);
        return Result.ok(list);
    }


    @GetMapping("queryArticlePage")
    @RateLimiter
    public Result<?> getWxArticleList(@RequestParam(name = "offset", defaultValue = "0") Integer offset,
                                      @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
                                      @RequestParam String sortBy) throws IOException {

        SearchRequest.Builder builder = new SearchRequest.Builder();
        builder.index(CacheConstant.ES_INDEX)
                .query(q -> q.term(t -> t
                        .field("delFlag")
                        .value(0)
                ))
                .sort(sort -> sort
                        .field(f -> f
                                .field(sortBy)
                                .order(co.elastic.clients.elasticsearch._types.SortOrder.Desc)
                        )
                )
                .source(source -> source
                        .filter(f -> f
                                .excludes("html", "content")
                        )
                )
                .from(offset)
                .size(pageSize);
        SearchResponse<ArticleManageDto> search = restHighLevelClient.search(builder.build(),
                ArticleManageDto.class);
        List<ArticleManageDto> result = new ArrayList<>();
        for (Hit<ArticleManageDto> hit : search.hits().hits()) {
            ArticleManageDto source = hit.source();
            result.add(source);
        }
        Map<String, Object> map = new HashMap<>();
        map.put("total", search.hits().total().value());
        map.put("topics", result);
        Double num = Math.ceil(result.size() / pageSize);
        int i = num.intValue();
        if (i == 0) {
            map.put("lastPage", "nomore");
        }
        return Result.ok(map);
    }

    @GetMapping("/queryArticleDetail")
    @RateLimiter
    public Result<?> getWxArticleDetail(@RequestParam String id) throws IOException {
        GetResponse<ArticleManageDto> response = restHighLevelClient.get(builder -> builder.index(CacheConstant.ES_INDEX).id(id), ArticleManageDto.class);
        ArticleManageDto entity = response.source();
        boolean login = StpUtil.isLogin();
        if (login) {
            SysUserVo user = entity.getUser();
            String username = StpUtil.getLoginIdAsString();// 获取当前会话账号id, 并转化为`String`类型
            LambdaQueryWrapper<ArticleLikeCollection> lqw = new LambdaQueryWrapper<>();
            lqw.eq(ArticleLikeCollection::getUsername, username)
                    .eq(ArticleLikeCollection::getArticleId, id);
            ArticleLikeCollection articleLikeCollection = articleLikeCollectionService.getOne(lqw);
            if (articleLikeCollection != null) {
                user.setLike(true);
            }
            LambdaQueryWrapper<ArticleFavoritesSub> lqw2 = new LambdaQueryWrapper<>();
            lqw2.eq(ArticleFavoritesSub::getCreateBy, username)
                    .eq(ArticleFavoritesSub::getArticleId, id);
            ArticleFavoritesSub articleFavoritesSub = articleFavoritesSubService.getOne(lqw2);
            if (articleFavoritesSub != null) {
                user.setCollect(true);
            }
            LambdaQueryWrapper<ArticleFollow> lqw3 = new LambdaQueryWrapper<>();
            lqw3.eq(ArticleFollow::getUsername, entity.getCreateBy())
                    .eq(ArticleFollow::getCreateBy, username);
            ArticleFollow articleFollow = articleFollowService.getOne(lqw3);
            if (articleFollow != null) {
                user.setFollow(true);
            }
        }

        return Result.ok(entity);
    }


    /**
     * 根据标签ID查找文章
     *
     * @param id 标签id
     * @return
     * @throws IOException
     */
    @GetMapping("/queryArticleByLableId")
    @RateLimiter
    public Result<?> queryArticleByLableId(@RequestParam String id,
                                           @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
                                           @RequestParam(name = "offset", defaultValue = "0") Integer offset) throws IOException {
        Map<String, Object> map = new HashMap<>();
        ArticleLable articleLable = articleLableService.getById(id);
        map.put("subject", articleLable);

        SearchRequest.Builder builder = new SearchRequest.Builder();
        builder.index(CacheConstant.ES_INDEX);
        builder.query(q -> q.term(t -> t
                .field("delFlag")
                .value(0)
        ));
        builder.query(q -> q.fuzzy(f -> f
                .field("articleLable")
                .value(id)
                .fuzziness("1")
        ));
        builder
                .source(source -> source
                        .filter(f -> f
                                .excludes("html", "content")
                        )
                )
                .from(offset).size(pageSize);
        SearchResponse<ArticleManageDto> search = restHighLevelClient.search(builder.build(),
                ArticleManageDto.class);
        List<ArticleManageDto> result = new ArrayList<>();
        for (Hit<ArticleManageDto> hit : search.hits().hits()) {
            ArticleManageDto source = hit.source();
            result.add(source);
        }
        map.put("total", search.hits().total().value());
        map.put("topics", result);
        Double num = Math.ceil(result.size() / pageSize);
        int i = num.intValue();
        if (i == 0) {
            map.put("lastPage", "nomore");
        }
        return Result.ok(map);
    }

    /**
     * 根据分类ID查找文章
     *
     * @return
     */
    @GetMapping("/queryArticleBySortId")
    @RateLimiter
    public Result<?> queryArticleBySortId(@RequestParam String sortId,
                                          @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
                                          @RequestParam(name = "offset", defaultValue = "0") Integer offset) throws IOException {
        SearchRequest.Builder builder = new SearchRequest.Builder();
        builder.index(CacheConstant.ES_INDEX)
                .query(queryBuilder -> queryBuilder
                        .bool(boolQueryBuilder -> boolQueryBuilder
                                .must(queryBuilder2 -> queryBuilder2
                                        .term(matchQueryBuilder -> matchQueryBuilder
                                                .field("articleSort").value(sortId))
                                )
                                .must(queryBuilder2 -> queryBuilder2
                                        .term(rangeQueryBuilder -> rangeQueryBuilder
                                                .field("delFlag").value(0))
                                )
                        ))
                .source(source -> source
                        .filter(f -> f
                                .excludes("html", "content")
                        )
                )
                .from(offset)
                .size(pageSize);
        SearchResponse<ArticleManageDto> search = restHighLevelClient.search(builder.build(),
                ArticleManageDto.class);
        List<ArticleManageDto> result = new ArrayList<>();
        for (Hit<ArticleManageDto> hit : search.hits().hits()) {
            ArticleManageDto source = hit.source();
            result.add(source);
        }
        Map<String, Object> map = new HashMap<>();
        Double num = Math.ceil(result.size() / pageSize);
        int i = num.intValue();
        if (i == 0) {
            map.put("lastPage", "nomore");
        }
        map.put("data", result);
        map.put("total", search.hits().total().value());
        return Result.ok(map);
    }

    /**
     * 根据ID查询分类
     *
     * @return
     */
    @GetMapping("/querySortById")
    @RateLimiter
    public Result<?> querySortById(@RequestParam String id) {
        Map<String, Object> map = articleSortService.getWxSortById(id);
        return Result.ok(map);
    }

    /**
     * 获取所有分类
     *
     * @return
     */
    @GetMapping("/querySortAll")
    @RateLimiter
    public Result<?> querySortAll() {
        Map<String, Object> map = new HashMap<>();
        List<Map<String, Object>> tabs = articleSortService.getWxArticleSortList();
        map.put("tabs", tabs);
        map.put("cur_tab", tabs.get(0).get("id"));
        return Result.ok(map);
    }

    /**
     * 查询全部标签已经我的标签
     *
     * @return
     * @throws IOException
     */
    @GetMapping("/queryLableStatistics")
    @RateLimiter
    public Result<?> queryLableStatistics() {
        Map<String, Object> map = new HashMap<>();
        boolean login = StpUtil.isLogin();
        List<ArticleManageVo> mys = new ArrayList<>();
        if (login) {
            String username = StpUtil.getLoginIdAsString();
            mys = articleManageService.initArticleLable(username);
        }
        List<ArticleManageVo> list = articleManageService.initArticleLable("");
        map.put("alls", list);
        map.put("mys", mys);

        return Result.ok(map);
    }

    /**
     * 综合页面-左侧菜单
     *
     * @return
     */
    @GetMapping("/queryMomprehensiveMenu")
    @RateLimiter
    public Result<?> queryMomprehensiveMenu() {
        Map<String, Object> map = new HashMap<>();
        List<Map<String, String>> slide = sysBaseAPI.getExtensionList();
        map.put("slides", slide);
        List<Map<String, String>> tabs = new ArrayList<>();
        Map<String, String> friendLinkMap = new HashMap<>();
        friendLinkMap.put("id", "friendLink");
        friendLinkMap.put("name", "友链");
        Map<String, String> technologyMap = new HashMap<>();
        technologyMap.put("id", "technology");
        technologyMap.put("name", "技术栈");
//        Map<String, String> wallpaperMap = new HashMap<>();
//        wallpaperMap.put("id", "wallpaper");
//        wallpaperMap.put("name", "壁纸");
        Map<String, String> archiveMap = new HashMap<>();
        archiveMap.put("id", "archive");
        archiveMap.put("name", "归档");
        tabs.add(friendLinkMap);
        tabs.add(technologyMap);
//        tabs.add(wallpaperMap);
        tabs.add(archiveMap);
        map.put("tabs", tabs);
        map.put("cur_tab", "friendLink");
        return Result.ok(map);
    }

    /**
     * @return
     * @功能：全文检索 根据标题、内容检索文章
     */
    @GetMapping("/globalSearch")
    @RateLimiter
    public Result<?> globalSearch(@RequestParam String keyword,
                                  @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
                                  @RequestParam(name = "offset", defaultValue = "0") Integer offset) throws IOException {

        SearchRequest.Builder builder = new SearchRequest.Builder();
        builder.index(CacheConstant.ES_INDEX)
                .query(q -> q.term(t -> t
                        .field("delFlag")
                        .value(0)
                ))
                .query(q -> q.multiMatch(m -> m.
                        fields("title", "abstractText")
                        .query(keyword)))
                .highlight(h -> h
                        .fields("title", highlightFieldBuilder -> highlightFieldBuilder)
                        .fields("abstractText", highlightFieldBuilder -> highlightFieldBuilder)
                        .preTags("<font color='red'>")
                        .postTags("</font>")
                )
                .sort(sort -> sort
                        .field(f -> f
                                .field("publishTime")
                                .order(co.elastic.clients.elasticsearch._types.SortOrder.Desc)
                        )
                )
                .source(source -> source
                        .filter(f -> f
                                .excludes("html", "content")
                        )
                );
        SearchResponse<ArticleManageDto> search = restHighLevelClient.search(builder.build(),
                ArticleManageDto.class);
        List<ArticleManageDto> result = new ArrayList<>();
        for (Hit<ArticleManageDto> hit : search.hits().hits()) {
            ArticleManageDto source = hit.source();
            for (Map.Entry<String, List<String>> entry : hit.highlight().entrySet()) {
                ReflectUtil.setFieldValue(source, entry.getKey(), entry.getValue().get(0));
            }
            result.add(source);
        }
        Map<String, Object> map = new HashMap<>();
        map.put("total", search.hits().total().value());
        map.put("topics", result);
        Double num = Math.ceil(result.size() / pageSize);
        int i = num.intValue();
        if (i == 0) {
            map.put("lastPage", "nomore");
        }
        return Result.ok(map);
    }

    @AutoLog(value = "获取跳转小程序指定页面 二维码（用于海报）")
    @ApiOperation(value = "获取跳转小程序指定页面 二维码（用于海报）", notes = "获取跳转小程序指定页面 二维码（用于海报）")
    @GetMapping("/queryPosterUrl")
    public Result<?> queryPosterUrl(@RequestParam String post_id) throws Exception {
        boolean objectExist = MinioUtil.isObjectExist(bucketName, "wxCode" + "/" + post_id + ".png");
        String wxCodeUrl = "";
        if (!objectExist) {
            String appid = "wx5515300d09cbf231";
            String secret = "3dd88263d7156f526e26d6d13ead687a";
            String accessTokenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appid + "&secret=" + secret;
            String result = HttpUtil.get(accessTokenUrl);
            JSONObject jsonObject = JSONUtil.parseObj(result);
            String accessToken = jsonObject.get("access_token").toString();

            //文档地址 https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/qr-code/wxacode.getUnlimited.html#%E8%AF%B7%E6%B1%82%E5%8F%82%E6%95%B0

            String url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" + accessToken;

            // 发送请求参数
            JSONObject paramJson = new JSONObject();
            paramJson.set("page", "pages/article/article");
//        paramJson.put("check_path", false);
            paramJson.put("width", 280);
            paramJson.set("scene", post_id);
            //设置小程序码版本
            //paramJson.put("env_version","release"); 默认正式
//        paramJson.put("env_version", "trial"); //体验版
//        paramJson.put("env_version", "develop"); //开发版

//        String post = HttpUtil.post(url, paramJson.toString());
//        System.out.println(post);
            InputStream inputStream = RestUtil.postInputStream(url, paramJson);
            String name = post_id + ".png";//文件名加后缀，跟上面对应
            saveToImgByInputStream(inputStream, upLoadPath + File.separator + "wxCode", name);  //保存图片
            InputStream file = FileUtil.getInputStream(upLoadPath + File.separator + "wxCode" + File.separator + name);
            wxCodeUrl = MinioUtil.wxCodeUpload(file, null, post_id);
            FileUtil.del(upLoadPath + File.separator + "wxCode" + File.separator + name);
        } else {
            wxCodeUrl = MinioUtil.getObjectURL(bucketName, "wxCode" + "/" + post_id + ".png", 360);

        }
        return Result.ok(wxCodeUrl);
    }

    /**
     * 将二进制转换成文件保存
     *
     * @param instreams 二进制流
     * @param imgPath   图片的保存路径
     * @param imgName   图片的名称
     * @return 1：保存正常
     * 0：保存失败
     */
    public static int saveToImgByInputStream(InputStream instreams, String imgPath, String imgName) {
        int stateInt = 1;
        if (instreams != null) {
            try {
                File file = new File(imgPath, imgName);//可以是任何图片格式.jpg,.png等
                File filePath = new File(imgPath);
                if (!filePath.exists()) {
                    filePath.mkdirs();// 创建文件根目录
                }
                FileOutputStream fos = new FileOutputStream(file);
                byte[] b = new byte[1024];
                int nRead = 0;
                while ((nRead = instreams.read(b)) != -1) {
                    fos.write(b, 0, nRead);
                }
                fos.flush();
                fos.close();
            } catch (Exception e) {
                stateInt = 0;
                e.printStackTrace();
            } finally {
            }
        }
        return stateInt;//1 成功，0 失败
    }

    /**
     * @return
     * @功能：全文检索 根据标题、内容检索文章
     */
    @GetMapping("/user/home/userInfo")
    @RateLimiter
    public Result<?> searchWX(@RequestParam(required = false) String username) {
        Integer beLikedNum = 0;
        long articleNum = 0;
        long followNum = 0;
        long fansNum = 0;
        String joinTime = "";
        username = StrUtil.isBlank(username) ? StpUtil.getLoginIdAsString() : username;// 获取当前会话账号id, 并转化为`String`类型
        beLikedNum = articleManageService.beLiked(username);
        LambdaQueryWrapper<ArticleManage> articleLqw = new LambdaQueryWrapper<>();
        articleLqw.eq(ArticleManage::getCreateBy, username).eq(ArticleManage::getDelFlag, "0");
        articleNum = articleManageService.count(articleLqw);

        LambdaQueryWrapper<ArticleFollow> followLqw = new LambdaQueryWrapper<>();
        // 获取关注
        followLqw.eq(ArticleFollow::getCreateBy, username);
        followNum = articleFollowService.count(followLqw);
        // 获取粉丝
        followLqw.clear();
        followLqw.eq(ArticleFollow::getUsername, username);
        fansNum = articleFollowService.count(followLqw);

        LoginUser loginUser = sysBaseAPI.getUserByName(username);
        joinTime = DateUtil.formatBetween(loginUser.getCreateTime(), DateUtil.date(), BetweenFormatter.Level.MINUTE);

        // 是否关注
        LambdaQueryWrapper<ArticleFollow> lqw3 = new LambdaQueryWrapper<>();
        lqw3.eq(ArticleFollow::getUsername, username)
                .eq(ArticleFollow::getCreateBy, StrUtil.isBlank(username) ? StpUtil.getLoginIdAsString() : username);
        ArticleFollow articleFollow = articleFollowService.getOne(lqw3);
        LambdaQueryWrapper<ArticleFollow> lqw4 = new LambdaQueryWrapper<>();
        lqw4.eq(ArticleFollow::getUsername, StrUtil.isBlank(username) ? StpUtil.getLoginIdAsString() : username)
                .eq(ArticleFollow::getCreateBy, username);
        ArticleFollow articleFollow1 = articleFollowService.getOne(lqw4);

        Map<String, Object> map = new HashMap<>();
        map.put("beLikedNum", beLikedNum);
        map.put("articleNum", articleNum);
        map.put("followNum", followNum);
        map.put("fansNum", fansNum);
        map.put("joinTime", joinTime);
        map.put("loginUser", loginUser);
        map.put("isMe", StrUtil.isBlank(username) ? true : username.equals(StrUtil.isBlank(username) ? StpUtil.getLoginIdAsString() : username) ? true : false);
        map.put("isFollow", ObjectUtil.isNull(articleFollow) ? false : true);
        map.put("isFans", ObjectUtil.isNotNull(articleFollow) && ObjectUtil.isNotNull(articleFollow1) ? true : false);

        return Result.ok(map);
    }


    /**
     * @return
     * @功能：归档 根据id
     */
    @GetMapping("/queryArticleGroupByCreateTime")
    @RateLimiter
    public Result<?> queryArticleGroupByCreateTime() {
        List<Map<String, Object>> listMaps = articleManageService.articleGroupByCreateTime(null);
        listMaps.forEach(e -> {
            String createMonth = String.valueOf(e.get("createMonth"));
            List<ArticleManage> list = articleManageService.getArticleByTime(createMonth, null);
            e.put("data", list);
        });
        return Result.ok(listMaps);
    }

    /**
     * 我的页面-统计-作品、粉丝、关注、获赞-数量
     *
     * @return
     * @throws IOException
     */
    @GetMapping("/queryMyPageStatistics")
    @RateLimiter
    public Result<?> queryMyPageStatistics() throws IOException {
        boolean login = StpUtil.isLogin();
        Integer beLikedNum = 0;
        long articleNum = 0;
        long followNum = 0;
        long fansNum = 0;
        String joinTime = "";
        if (login) {
            String username = StpUtil.getLoginIdAsString();// 获取当前会话账号id, 并转化为`String`类型
            beLikedNum = articleManageService.beLiked(username);
            LambdaQueryWrapper<ArticleManage> articleLqw = new LambdaQueryWrapper<>();
            articleLqw.eq(ArticleManage::getCreateBy, username).eq(ArticleManage::getDelFlag, "0");
            articleNum = articleManageService.count(articleLqw);

            LambdaQueryWrapper<ArticleFollow> followLqw = new LambdaQueryWrapper<>();
            // 获取关注
            followLqw.eq(ArticleFollow::getCreateBy, username);
            followNum = articleFollowService.count(followLqw);
            // 获取粉丝
            followLqw.clear();
            followLqw.eq(ArticleFollow::getUsername, username);
            fansNum = articleFollowService.count(followLqw);

            LoginUser loginUser = sysBaseAPI.getUserByName(username);
            joinTime = DateUtil.formatBetween(loginUser.getCreateTime(), DateUtil.date(), BetweenFormatter.Level.MINUTE);

        }
        Map<String, Object> map = new HashMap<>();
        map.put("beLikedNum", beLikedNum);
        map.put("articleNum", articleNum);
        map.put("followNum", followNum);
        map.put("fansNum", fansNum);
        map.put("login", login);
        map.put("joinTime", joinTime);

        return Result.ok(map);
    }

    /**
     * 个人主页根据-收藏、点赞、文章-查找文章
     *
     * @param username
     * @return
     */
    @GetMapping("/queryPersonPageArticle")
    @RateLimiter
    public Result<?> queryPersonPageArticle(@RequestParam(required = false) String username,
                                            @RequestParam String tab,
                                            @RequestParam(name = "offset", defaultValue = "0") Integer offset) {
        username = StrUtil.isBlank(username) ? StpUtil.getLoginIdAsString() : username;// 获取当前会话账号id, 并转化为`String`类型
        List<ArticleManageDto> resultList = null;
        if ("fav".equals(tab)) {
            resultList = articleManageService.getPersonMyFavoritesList(username, offset, 10);
        } else if ("like".equals(tab)) {
            resultList = articleManageService.getPersonLikeList(username, offset, 10);
        } else if ("publish".equals(tab)) {
            resultList = articleManageService.getArticleByUser(username, offset, 10);
        }
        for (ArticleManageDto entity : resultList) {
            genArticleManageDto(entity);
        }
        Map<String, Object> map = new HashMap<>();
        map.put("topics", resultList);
        Double num = Math.ceil(resultList.size() / 10);
        int i = num.intValue();
        if (i == 0) {
            map.put("lastPage", "nomore");
        }
        return Result.ok(map);
    }

    private void genArticleManageDto(ArticleManageDto articleManage) {
        String id = articleManage.getId();
        // 获取分类
        ArticleSort articleSort = articleSortService.getById(articleManage.getArticleSort());
        articleManage.setArticleSort_dictText(articleSort.getName());
        articleManage.setSort(articleSort);
        // 获取标签
        String[] lables = articleManage.getArticleLable().split(",");
        List<ArticleLable> articleLableList = articleLableService.listByIds(Arrays.asList(lables));
        articleManage.setTags(articleLableList);
        List<String> lableNames = articleLableList.stream().map(ArticleLable::getName).collect(Collectors.toList());
        articleManage.setArticleLable_dictText(StringUtils.join(lableNames, ","));
        // 获取用户
        String username = articleManage.getCreateBy();
        LoginUser user = sysBaseAPI.getUserByName(username);
        SysUserVo userVo = new SysUserVo();
        BeanUtils.copyProperties(user, userVo);
        articleManage.setUser(userVo);

        // 获取文章点赞用户
        List<Map<String, String>> like_list = articleLikeCollectionService.getWxArticleLikeUser(id);
        articleManage.setLikeList(like_list);

    }

    /**
     * 查询关注的用户
     *
     * @param username
     * @return
     */
    @GetMapping("/queryMyFollowUsers")
    @RateLimiter
    public Result<?> queryMyFollowUsers(@RequestParam(required = false) String username,
                                        @RequestParam(name = "offset", defaultValue = "0") Integer offset) {
        username = StrUtil.isBlank(username) ? StpUtil.getLoginIdAsString() : username;// 获取当前会话账号id, 并转化为`String`类型
        List<Map<String, Object>> list = articleFollowService.myFollows(username, offset, 10);
        for (Map<String, Object> map : list) {
            map.put("is_follow", true);
            // 是否互关
            LambdaQueryWrapper<ArticleFollow> lqw = new LambdaQueryWrapper<>();
            lqw.eq(ArticleFollow::getUsername, username).eq(ArticleFollow::getCreateBy, map.get("username"));
            ArticleFollow one = articleFollowService.getOne(lqw);
            if (ObjectUtil.isNotNull(one)) {
                map.put("is_fans", true);
            } else {
                map.put("is_fans", false);
            }
        }
        return Result.ok(list);
    }

    /**
     * 我的粉丝
     *
     * @param username
     * @return
     */
    @GetMapping("/queryMyFans")
    @RateLimiter
    public Result<?> queryMyFans(@RequestParam(required = false) String username,
                                 @RequestParam(name = "offset", defaultValue = "0") Integer offset) {
        username = StrUtil.isBlank(username) ? StpUtil.getLoginIdAsString() : username;// 获取当前会话账号id, 并转化为`String`类型
        List<Map<String, Object>> list = articleFollowService.myFans(username, offset, 10);
        for (Map<String, Object> map : list) {
            map.put("is_fans", true);
            // 是否关注
            LambdaQueryWrapper<ArticleFollow> lqw = new LambdaQueryWrapper<>();
            lqw.eq(ArticleFollow::getUsername, map.get("username")).eq(ArticleFollow::getCreateBy, username);
            ArticleFollow one = articleFollowService.getOne(lqw);
            if (ObjectUtil.isNotNull(one)) {
                map.put("is_follow", true);
            } else {
                map.put("is_follow", false);
            }
        }
        return Result.ok(list);
    }
}
